/* 
 * Created on 2006-10-16
 * Last modified on 2009-12-15
 * Powered by YeQiangWei.com
 */
package com.yeqiangwei.commons.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

import com.yeqiangwei.commons.util.StringHelper;
import com.yeqiangwei.commons.util.ValidatorHelper;

public class FileHelper implements java.io.Serializable{

	/**
	 * 
	 */
	
	private static final long serialVersionUID = 5437208056045724357L;

	private static final Logger logger = Logger.getLogger(FileHelper.class);

	public static final String separator = java.io.File.separator;

	
	public static void main(String srgs[]) {
		File f = FileHelper.findDirectory(new File("/opt/www/fadadianqi.com/target/webapp"), "classes");
		System.out.println(f);
	}
	
	public static final File findDirectory(File d, String name) {
		return _findDirectory(d, name);
	}
	
	private static final File _findDirectory(File d, String name) {
		File[] list = d.listFiles();
		File dir = null;
		if(list != null) {
			for(File f : list) {
				if(f.isFile()) {
					continue;
				}
				if(f.getName().equalsIgnoreCase(name)) {
					dir = f;
					System.out.println("#####" + dir);
					break;
				}
				else {
					dir = _findDirectory(f, name);
					if(dir != null) {
						break;
					}
				}
			}
		}
		return dir;
	}

	/**
	 * 根据含路径的文件名提取文件扩展名
	 * 
	 * @param path
	 * @return
	 */
	public static String getFileExt(String path) {
		if (path == null)
			return null;
		int begin = path.lastIndexOf(".") + 1;
		if (begin == -1){
			return null;
		}
		int end = path.length();
		String str = path.substring(begin, end).toLowerCase();
		if(str.indexOf("jpg") != -1 && !str.endsWith("jpg")){
			str = "jpg";
		}
		else if(str.indexOf("jpeg") != -1 && !str.endsWith("jpeg")){
			str = "jpeg";
		}
		else if(str.indexOf("gif") != -1 && !str.endsWith("gif")){
			str = "gif";
		}
		else if(str.indexOf("png") != -1 && !str.endsWith("png")){
			str = "png";
		}
		return str;
	}

	public static String getMimeType(String filepath) {
		String osname = System.getProperty("os.name");
		String mimeType = null;
		if ("linux".equalsIgnoreCase(osname) || "unix".equalsIgnoreCase(osname)
				|| osname.equalsIgnoreCase("freebsd")) {
			String pm = " -i ";
			Process process;
			InputStream inputStream = null;
			try {
				process = Runtime.getRuntime().exec("file" + pm + filepath);
				inputStream = process.getInputStream();
			} catch (IOException e1) {
				logger.error(e1.toString());
			}
			if (inputStream == null) {
				return null;
			}
			InputStreamReader isr = new InputStreamReader(inputStream);
			BufferedReader bufferedReader = new BufferedReader(isr);
			try {
				mimeType = bufferedReader.readLine();
			} catch (IOException e1) {
				logger.error(e1.toString());
			} finally{
				try {
					bufferedReader.close();
				} catch (IOException e1) {
					logger.error(e1.toString());
				}
			}
			if (mimeType == null) {
				return null;
			}
			int s = mimeType.indexOf(":");
			int e = mimeType.indexOf(";");
			if (s != -1 && e != -1) {
				mimeType = StringHelper.substring(
						mimeType, s + 1, e, mimeType).trim();
			}
			else if(s != -1 && e == -1) {
				mimeType = StringHelper.substring(
						mimeType, s + 1, mimeType.length(), mimeType).trim();
			}
		}
		return mimeType;
	}

	/**
	 * 根据含URL的文件地址提取文件名，含扩展名。
	 * 
	 * @param fileNameAndUrl
	 * @return
	 */
	public static String getFileName(String fileNameAndUrl) {
		if (fileNameAndUrl == null)
			return null;
		int fileNameStart = fileNameAndUrl.lastIndexOf(java.io.File.separator);
		if (fileNameStart == -1)
			fileNameStart = fileNameAndUrl.lastIndexOf("/");
		if (fileNameStart == -1) {
			fileNameStart = 0;
		} else {
			fileNameStart += 1;
		}
		return fileNameAndUrl.substring(fileNameStart, fileNameAndUrl.length()).trim();
	}

	/**
	 * 读取文本文件内容
	 * 
	 * @param filePathAndName
	 *            带有完整绝对路径的文件名
	 * @param encoding
	 *            文本文件打开的编码方式
	 * @return 返回文本文件的内容
	 * @throws IOException
	 * @deprecated
	 */
	public static String readTxt(String filePathAndName, String encoding) throws IOException {
		StringBuffer str = new StringBuffer();
		FileInputStream fs = new FileInputStream(filePathAndName);
		InputStreamReader isr;
		if (ValidatorHelper.isEmpty(encoding)) {
			isr = new InputStreamReader(fs);
		} else {
			isr = new InputStreamReader(fs, encoding);
		}
		BufferedReader br = new BufferedReader(isr);
		String data;
		while ((data = br.readLine()) != null) {
			str.append(data + "\n");
		}
		br.close();
		isr.close();
		fs.close();
		return str.toString();
	}

	/**
	 * 
	 * @param filePathAndName
	 * @param encoding
	 * @return
	 * @throws IOException
	 */
	public static String readText(String filePathAndName, String encoding) 
			throws IOException 
	{
		return readText(new FileInputStream(filePathAndName), encoding);
	}
	
	/**
	 * 
	 * @param file
	 * @param encoding
	 * @return
	 * @throws IOException
	 */
	public static String readText(java.io.File file, String encoding)
			throws IOException 
	{
		return readText(new FileInputStream(file), encoding);
	}
	
	/**
	 * 
	 * @param fileInputStream
	 * @param encoding
	 * @return
	 * @throws IOException
	 */
	public static String readText(FileInputStream fileInputStream
			, String encoding) throws IOException
	{
		InputStreamReader read = new InputStreamReader(fileInputStream, encoding);
		BufferedReader reader = new BufferedReader(read);
		String line;
		StringBuilder sb = new StringBuilder();
		while ((line = reader.readLine()) != null) {
			sb.append(line);
			sb.append("\n");
		}
		reader.close();
		read.close();
		return sb.toString();
	}

	/**
	 * 获取当前目录下的所有目录
	 * 
	 * @return
	 */
	public static List<java.io.File> getCurrentDirectories(String path) {
		List<java.io.File> directories = null;
		java.io.File file = new java.io.File(path);
		java.io.File[] files = file.listFiles();
		if (!ValidatorHelper.isEmpty(files)) {
			directories = new ArrayList<java.io.File>();
			for (java.io.File f : files) {
				if (f.isDirectory()) {
					directories.add(f);
				}
			}
		}
		return directories;
	}

	/**
	 * 新建目录
	 * 
	 * @param pathAndName
	 *            路径+目录名
	 * @return boolean
	 */
	public static boolean createFolder(String pathAndName) {
		java.io.File file = new java.io.File(pathAndName);
		if (!file.exists()) {
			return file.mkdirs();
		} else {
			return true;
		}
	}

	public static boolean initpath(StringBuilder path) {
		return initpath(path.toString());
	}
	
	/**
	 * 自动初始化路径，如果目录不存在则自动创建
	 * 
	 * @param path
	 * @return boolean
	 */
	public static boolean initpath(String path) {
		boolean bea = false;
		String pathtoken = null;
		String letter = ""; // 盘符
		if (path.indexOf(":") != -1) { // 如果是win系统
			pathtoken = StringHelper.substring(path, path.indexOf(":") + 1, path.length(), path);
			letter = StringHelper.substring(path, 0, path.indexOf(":") + 1, path);
		} else {
			pathtoken = path;
		}
		pathtoken = pathtoken.replace("/", separator).replace("\\", separator);
		if (!pathtoken.startsWith(separator)) {
			pathtoken = separator + pathtoken;
		}
		StringTokenizer st = new StringTokenizer(pathtoken, separator);
		String folder = letter;
		for (int i = 0; st.hasMoreTokens(); i++) {
			folder = folder + separator + st.nextToken();
			bea = createFolder(folder);
			if (!bea) {
				//throw new RuntimeException("create folder failed, path = " + folder);
			}
		}
		return bea;
	}

	/**
	 * 多级目录创建
	 * 
	 * @param basepath
	 *            准备要在本级目录下创建新目录的目录路径 例如 c:\myf
	 * @param paths
	 *            无限级目录参数，各级目录以单数线区分 例如 a|b|c
	 * @return 返回创建文件后的路径 例如 c:\myf\a\b\c\
	 */
	public static String createFolders(String basepath, String paths) {
		StringBuffer buf = new StringBuffer(basepath);
		if (basepath.endsWith(FileHelper.separator)) {
			buf.append(FileHelper.separator);
		}
		StringTokenizer st = new StringTokenizer(paths, "|");
		for (int i = 0; st.hasMoreTokens(); i++) {
			buf.append(st.nextToken());
			buf.append(File.separator);
			if (!createFolder(buf.toString())) {
				return null;
			}
		}
		return basepath;
	}

	/**
	 * 
	 * 新建文件
	 * 
	 * @param filePathAndName
	 *            文本文件完整绝对路径及文件名
	 * @param fileContent
	 *            文本文件内容
	 * @author YeQiangWei Studio by 我容易么我
	 * @throws IOException
	 */
	public static void createFile(String filePathAndName, String fileContent) throws IOException {
		createFile(filePathAndName, fileContent, "UTF-8", true);
	}

	/**
	 * 
	 * @param filePathAndName
	 * @param fileContent
	 * @param encoding
	 * @param override
	 * @throws IOException
	 */
	public static void createFile(String filePathAndName, String fileContent,
			String encoding, boolean override) throws IOException {
		if (ValidatorHelper.isEmpty(filePathAndName)) {
			return;
		}
		java.io.File newFile = new java.io.File(filePathAndName.toString());
		/*
		 * 如果文件不存在，要求自动覆盖！
		 */
		if (!override && newFile.exists()) { // 不覆盖
			logger.info(newFile.getAbsoluteFile() + " exists...");
			return;
		}
		PrintWriter myFile = null;
		if (!ValidatorHelper.isEmpty(encoding)) {
			myFile = new PrintWriter(newFile, encoding);
		} else {
			myFile = new PrintWriter(newFile);
		}
		if (!newFile.exists()) {
			boolean bea = newFile.createNewFile();
			if(!bea){
				throw new IOException("...... Failed to create new File: " 
						+ newFile.getAbsolutePath());
			}
			myFile.print(fileContent);
			myFile.close();
		} else {
			myFile.print(fileContent);
			myFile.close();
		}
	}

	/**
	 * 删除文件
	 * 
	 * @param filePathAndName
	 *            文本文件完整绝对路径及文件名
	 * @return Boolean 成功删除返回true遭遇异常返回false
	 * @author YeQiangWei Studio by 我容易么我
	 */
	public static boolean deleteFile(String path) {
		return deleteFile(new File(path));
	}
	
	public static boolean deleteFile(File file) {
		if(file.exists()){
			return file.delete();
		}
		return false;
	}

	/**
	 * 删除文件夹
	 * 
	 * @param folderPath
	 *            文件夹完整绝对路径
	 * @return
	 */
	public static boolean deleteFolder(String path) {
		deleteAllFile(path); // 删除完里面所有内容
		return new java.io.File(path).delete();
	}

	/**
	 * 删除指定文件夹下所有文件
	 * 
	 * @param path
	 *            文件夹完整绝对路径
	 * @return
	 * @return public static boolean deleteAllFile(String path) { boolean bea =
	 *         false; bea = deleteFolder(path); if(createFolder(path)!=null){
	 *         bea = true; } return bea; }
	 */

	public static boolean deleteAllFile(String path) {
		boolean bea = false;
		java.io.File file = new java.io.File(path);
		if (!file.exists()) {
			return bea;
		}
		if (!file.isDirectory()) {
			return bea;
		}
		String[] tempList = file.list();
		java.io.File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(FileHelper.separator)) {
				temp = new java.io.File(path + tempList[i]);
			} else {
				temp = new java.io.File(path + FileHelper.separator + tempList[i]);
			}
			if (temp.isFile()) {
				bea = temp.delete();
			}
			if (temp.isDirectory()) {
				bea = deleteAllFile(path + FileHelper.separator + tempList[i]);// 先删除文件夹里面的文件
			}
		}
		return bea;
	}

	/**
	 * 复制单个文件
	 * 
	 * @param sourcePath
	 *            准备复制的文件源
	 * @param targetPath
	 *            拷贝到新绝对路径带文件名
	 * @return
	 * @throws IOException
	 */
	public static boolean copyFile(String sourcePath, String targetPath)
			throws IOException {
		if(sourcePath.equals(targetPath)){
			return true;
		}
		int bytesum = 0;
		int byteread = 0;
		java.io.File source = new java.io.File(sourcePath);
		if (!source.exists()) { 
			// 如果源文件不存在则拷贝失败
			return false;
		}
		java.io.File target = new java.io.File(targetPath);
		if (target.exists()) {
			// 如果目标文件存在则删除它
			if(!target.delete()){
				throw new IOException("...... Can't delete " 
						+ source.getAbsolutePath());
			}
		}
		FileOutputStream outputStream = new FileOutputStream(target);
		InputStream inputStream = new FileInputStream(sourcePath); // 读入原文件
		byte[] buffer = new byte[1024];
		while ((byteread = inputStream.read(buffer)) != -1) {
			bytesum += byteread; // 字节数 文件大小
			outputStream.write(buffer, 0, byteread);
		}
		outputStream.flush();
		outputStream.close();
		inputStream.close();
		if(bytesum == 0){
			return false;
		}
		return true;
	}

	/**
	 * 
	 * @param sourcePath
	 * @param targetPath
	 * @return
	 * @throws IOException
	 */
	public static boolean copyFolder(String sourcePath, String targetPath) throws IOException {
		if(sourcePath.equals(targetPath)){
			return true;
		}
		else if(ValidatorHelper.isEmpty(sourcePath) || ValidatorHelper.isEmpty(targetPath)){
			return false;
		}
		java.io.File a = new java.io.File(sourcePath);
		if(!a.isDirectory()){
			logger.error("......" + sourcePath + " is not a Directory");
			return false;
		}
		if(targetPath.endsWith(FileHelper.separator) && !sourcePath.endsWith(FileHelper.separator)){
			String ofolder = StringHelper.substring(sourcePath, sourcePath.lastIndexOf(FileHelper.separator) + 1, sourcePath.length(), null);
			targetPath = targetPath + ofolder + FileHelper.separator;
		}
		FileHelper.initpath(targetPath); //初始化要copy到的目录，保证目录一定存在。
		String[] file = a.list();
		java.io.File temp = null;
		for (int i = 0; i < file.length; i++) {
			if (sourcePath.endsWith(FileHelper.separator)) {
				temp = new java.io.File(sourcePath + file[i]);
			} else {
				temp = new java.io.File(sourcePath + FileHelper.separator + file[i]);
			}
			if (temp.isFile()) {
				FileInputStream input = new java.io.FileInputStream(temp);
				FileOutputStream output = new java.io.FileOutputStream(targetPath + FileHelper.separator + (temp.getName()).toString());
				byte[] b = new byte[1024 * 5];
				int len;
				while ((len = input.read(b)) != -1) {
					output.write(b, 0, len);
				}
				output.flush();
				output.close();
				input.close();
			} else if (temp.isDirectory()) {// 如果是子文件夹
				copyFolder(sourcePath + FileHelper.separator + file[i], targetPath + FileHelper.separator + file[i]);
			}
		}
		return true;
	}

	/**
	 * 
	 * @param opath
	 * @param npath
	 * @return
	 * @throws IOException
	 */
	public static boolean moveFile(String opath, String npath) throws IOException {
		if (copyFile(opath, npath)) {
			return deleteFile(opath);
		}else{
			return false;
		}
	}

	/**
	 * 移动目录
	 * @param opath
	 * @param npath
	 * @return
	 * @throws IOException
	 */
	public static boolean moveFolder(String opath, String npath) throws IOException {
		if(copyFolder(opath, npath)){
			return deleteFolder(opath);
		}
		else{
			return false;
		}
	}

}
